import random
from typing import List, Union, Dict

from FileHandlers.JsonFile import JWriteSave
from data.Singleton import Singleton
from entiys.npc.NPCLoader import NPCLoader


class NPCSave(metaclass=Singleton):
    def __init__(self, saveName):
        self.save = saveName
        self.json = {}
        self.npcLoader = NPCLoader(saveName=self.save)

    def save2json(self):
        """
        把当前对象的JSON数据更新到存档中...
        :return:
        """
        JWriteSave(
            saveName=self.save,
            filename="npc",
            data=self.json
        )

    def update(self):
        """
        从npcLoader中对数据进行更新
        :return:
        """
        self.npcLoader.class_update()
        self.json = self.npcLoader.npcJson

    def setNpcAtttributeByMethod(self, method, attribute, value=None, valueMethod=None) -> bool:
        """
        根据传入的method筛选到指定的角色，然后
        :param method:
        :param attribute:
        :param value: 固定参数值
        :param valueMethod: 使用方法获取的不定参数值
        :return bool: 返回是否有符合条件的角色被设置
        """
        jsons = self.npcLoader.getByMethod(method)  # 查找角色

        # region 给角色的指定属性进行赋值
        if value is not None:
            jsons = self.update_attribute(jsons, attribute, value)
        elif valueMethod is not None:
            jsons = self.update_attribute(jsons, attribute, valueMethod=valueMethod)
        # endregion

        # region 保存到存档里
        if isinstance(jsons, list):
            for i in jsons:
                self.replaceCharajson(list(i.values()))
        elif isinstance(jsons, dict):
            self.replaceCharajson(list(jsons.values()))
        # endregion
        elif jsons is None:
            return False
        return True

    def update_attribute(self, json, attribute, value=None, valueMethod=None):
        """
        更新JSON 数组里面所有的attribute
        :return:
        """
        if json == []:
            # 没有角色存在
            return None

        def getValue(_json):
            nonlocal value, valueMethod
            print(_json)
            if value is None:
                value = valueMethod(_json)
                print(">>> ", value)

            return value

        if isinstance(json, list):
            total = []
            for data in json:
                data: dict
                total.append(self.update_attribute(
                    data,
                    attribute,
                    value,
                    valueMethod
                ))
            return total
        elif isinstance(json, dict):
            data = json
            for key in json.keys():
                data[key][attribute] = getValue(data[key])
            return data
        else:
            raise TypeError(f"the type of json must be the dict or the list, not {type(json)}")

    def setNpcAttributeByName(self, charaname, attribute, value=None, methodValue=None):
        """
        【pass】根据npc的名称对其的属性进行修改
        :param charaname: npc的名称
        :param attribute: 属性名称
        :param value: 属性值
        :param methodValue: 属性方法 自定义方法传入的user_json返回的值
        :return:
        """
        user_json: dict = self.npcLoader.getByName(charaname)
        assert user_json is not None, "[报错] 不存在NPC!"
        if value is not None:
            user_json[attribute] = value
        elif methodValue is not None:
            user_json[attribute] = methodValue(user_json)

        self.replaceCharajson(user_json)

    def replaceCharajson(self, charajson: Union[List, Dict], newname=None):
        """
        【pass】 [支持列表或者对象多种形式的charajson]
        使用新的npc的JSON更新在JSON数据中的npc的属性对象
        :param charajson:  {att:"xxx"} 或者是[{att:"xxx"},{att:"xxx"}]
        :return:
        """
        self.update()

        print(charajson)

        if isinstance(charajson, dict):
            if newname is None:  # 非新建角色
                _id = charajson.get("ID")
                copyJSON = self.json
                for npcName, npcAtt in self.json.items():
                    npcAtt: dict
                    if npcAtt.get("ID") == _id:
                        copyJSON[npcName] = charajson
                        break
            else:  # 新建角色
                self.json[charajson["name"]] = charajson
        elif isinstance(charajson, list):
            for i in charajson:
                assert isinstance(i, dict)
                self.replaceCharajson(i)

        self.save2json()

    def newNPCRandom(self):

        def generate_custom_random(probability_exponent, max_value):

            # 使用指数分布生成一个随机数
            rand_num = random.expovariate(1 / probability_exponent)

            # 将指数分布生成的随机数映射到1到max_value范围内
            scaled_rand_num = int((rand_num / (rand_num + max_value)) * max_value) + 1

            return scaled_rand_num

        # 生成一个随机数

        self.update()

        lenght = len(list(self.json.keys()))
        id = lenght + 1
        new_npc = {
            "ID": id,
            "name": "XX",
            "所在位置": "XX",
            "性格": "XX",
            "智商": 18,
            "动力": 13,
            "性能力": 8,
            "是否处女": True,
            "所属奴隶主": None,
            "是否死亡": False,
            "家政技能": 3,
            "格斗技能": 18,
            "管理技能": 16,
            "辅导技能": 14,
            "兽交": 0,
            "足交": 0,
            "乳交": 0,
            "手交": 0,
            "操逼": 0,
            "肛交": 0,
            "拳交": 0,
            "接吻": 0,
            "舔舌": 0,
            "口交": 0,
            "深喉": 0,
            "眼交": 0,
            "抖S": 0,
            "抖M": 0,
            "自慰": 0,
            "轮奸": 0,
            "色战主导能力": -2,
            "虫交": 0,
            "精神": 666,
            "死亡趋向": 0,
            "对你的忠诚度": 50,
            "做爱次数": 0,
            "乳头大小": random.choice(["贫乳","平乳","丰满", "巨乳"]),
            "统治国家": None,
            "衣服": "",
            "头饰": "",
            "项圈": None,
            "武器": "",
            "手环": None,
            "脚环": None,
            "下体装备": None,
            "效果": "",
            "忠于国家": "",
            "金钱": 0,
            "经营": None,
            "是否怀孕": False,
            "父亲": None,
            "母亲": None,
            "好友": None,
            "敌人": None,
            "和我的关系": 50,
            "爱欲度": 0,
            "爱欲度上限": 100,
            "性器": random.choice(["肉棒","蜜穴","蜜穴"]),
            "性别": random.choice(["男", "女", "女"])
        }

        for key in new_npc.keys():
            value = new_npc[key]
            if isinstance(value, int) and key != "ID":
                new_npc[key] = generate_custom_random(50, 100)

        return new_npc
